package ch.il07.converter.business.impl;

import java.util.List;

import ch.il07.converter.business.MeasurandAction;
import ch.il07.converter.persistence.Persistence;
import ch.il07.converter.persistence.PersistenceHelper;
import ch.il07.converter.persistence.entities.Measurand;
import ch.il07.converter.persistence.entities.Unit;
import ch.il07.converter.persistence.entities.User;
import ch.il07.converter.persistence.exceptions.PersistenceException;
import ch.il07.utils.logging.Level;
import ch.il07.utils.logging.Logger;
import ch.il07.utils.logging.LoggerHelper;

/**
 * @author danney
 * 
 */
public class MeasurandActionImpl implements MeasurandAction {

	private final static Logger LOGGER = LoggerHelper.getLogger();

	@Override
	public boolean deletePrivateMeasurand(String owner, String measurand) {
		try {
			Persistence persistence = PersistenceHelper.getPersistence();
			Measurand m = persistence.getMeasurand(measurand, owner);
			persistence.deleteMeasurand(m, owner);
			return true;
		} catch (PersistenceException e) {
			LOGGER.error("Error while invoking Persistence", e);
			return false;
		}
	}

	@Override
	public boolean deletePublicMeasurand(String measurand) {
		return deletePrivateMeasurand(null, measurand);
	}

	@Override
	public List<Measurand> getAllPrivateMeasurands(String owner) {
		try {
			return PersistenceHelper.getPersistence().getMeasurands(owner);
		} catch (PersistenceException e) {
			LOGGER.error("Error while invoking Persistence", e);
			return null;
		}
	}

	@Override
	public List<Measurand> getAllPublicMeasurands() {
		return getAllPrivateMeasurands(null);
	}

	@Override
	public boolean editMeasurand(String oldOwner, String newOwner,
			String oldName, String newName, String description) {
		if (oldName == null) {
			throw new IllegalArgumentException("oldName must not be null");
		}
		try {
			Persistence persistence = PersistenceHelper.getPersistence();
			Measurand measurandToBeUpdated = persistence.getMeasurand(oldName,
					oldOwner);
			if(measurandToBeUpdated == null) {
				LOGGER.error("editMeasurand: no measurand found with oldOwner ["+oldOwner+"] and oldName ["+oldName+"]");
				return false;
			}
			updateMeasurand(oldOwner, newOwner, oldName, newName, description,
					measurandToBeUpdated);
			persistence.updateMeasurand(measurandToBeUpdated);
			return true;
		} catch (PersistenceException e) {
			LOGGER.error("error while invoking Persistence", e);
			return false;
		}
	}

	private boolean updateMeasurand(String oldOwner, String newOwner,
			String oldName, String newName, String description,
			Measurand measurandToBeUpdated) {
		if (newOwner != null) {
			try {
				Persistence persistence = PersistenceHelper.getPersistence();
				User newUser = persistence.getUser(newOwner);
				measurandToBeUpdated.setOwner(newUser);
				if (LOGGER.isLoggable(Level.FINE)) {
					LOGGER.fine("editMeasurand: change owner [" + oldOwner
							+ "] to [" + newOwner + "]");
				}
			} catch (PersistenceException e) {
				LOGGER.error("error while invoking persistence", e);
				return false;
			}
		}
		if (description != null) {
			measurandToBeUpdated.setDescription(description);
			if (LOGGER.isLoggable(Level.FINE)) {
				LOGGER.fine("editMeasurand: change description to ["
						+ description + "]");
			}
		}
		measurandToBeUpdated.setName(newName);
		if (LOGGER.isLoggable(Level.FINE)) {
			LOGGER.fine("editMeasurand: change name [" + oldName + "] to ["
					+ newName + "]");
		}
		return true;
	}

	@Override
	public boolean addPublicMeasurand(String measurandName,
			String measurandDescription, String baseUnitName, String symbol) {
		if(measurandName == null) {
			throw new NullPointerException("measurandName must not be null");
		} else if (baseUnitName == null) {
			throw new NullPointerException("baseUnitName must not be null");
		}

		Unit u = new Unit(baseUnitName, 1D);
		u.setSymbol(symbol);
		Measurand measurand = new Measurand(measurandName, u);
		measurand.setDescription(measurandDescription);
		try {
			Persistence persistence = PersistenceHelper.getPersistence();
			persistence.addMeasurand(measurand, null);
			return true;
		} catch (PersistenceException e) {
			LOGGER.error("error while invoking Persistence", e);
			return false;
		}
	}

	@Override
	public boolean addPrivateMeasurand(String owner, String measurandName,
			String measurandDescription, String baseUnitName, String symbol) {
		if(measurandName == null) {
			throw new NullPointerException("measurandName must not be null");
		} else if (baseUnitName == null) {
			throw new NullPointerException("baseUnitName must not be null");
		} else if (owner == null) {
			throw new NullPointerException("owner must not be null");
		}

		try {
			Persistence persistence = PersistenceHelper.getPersistence();
			User user = persistence.getUser(owner);
			if (user == null) {
				LOGGER.error("the user with name " + user + "doesn't exist");
				return false;
			}
			Unit unit = new Unit(baseUnitName, 1D);
			unit.setSymbol(symbol);
			unit.setOwner(user);
			Measurand measurand = new Measurand(measurandName, unit);
			measurand.setDescription(measurandDescription);
			persistence.addMeasurand(measurand, owner);
			return true;
		} catch (PersistenceException e) {
			LOGGER.error("Error while invoking Persistence", e);
			return false;
		}
	}
}
